package com.github.linmt.dbdoc4j.utils;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * User: Linmt
 * Date: 2022/12/4
 * Time: 20:41
 * Description: ResultSet工具类
 */
public class ResultSetUtils {

    @FunctionalInterface
    public static interface ResultMapping<T> {
        T mapping(ResultSet resultSet);
    }

    public static <T> List<T> toObjectList(Class<T> clazz, ResultSet resultSet, ResultMapping<T> mapping) throws SQLException {
        List<T> list = new ArrayList<>();
        while (resultSet.next()) {
            list.add(toObject(clazz, resultSet, mapping));
        }

        return list;
    }

    public static <T> List<T> toObjectList(Class<T> clazz, ResultSet resultSet) throws SQLException {
        List<T> list = new ArrayList<>();
        while (resultSet.next()) {
            list.add(toObject(clazz, resultSet));
        }

        return list;
    }

    public static <T> T toObject(Class<T> clazz, ResultSet resultSet, ResultMapping<T> resultMapping) {
        return resultMapping.mapping(resultSet);
    }

    public static <T> T toObject(Class<T> clazz, ResultSet resultSet) {
        T t = null;
        try {
            t = clazz.newInstance();
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = NameUtils.toCamelCase(metaData.getColumnName(i));
                Field field = clazz.getDeclaredField(columnName);
                if (field == null) continue;

                field.setAccessible(true);
                field.set(t, resultSet.getObject(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return t;
    }
}
